<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Mobile App</title>
    <link rel="shortcut icon" href="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23673ab7' viewBox='0 0 16 16'%3E%3Cpath d='M6.375 7.125V4.658h1.78c.973 0 1.542.457 1.542 1.237 0 .802-.604 1.23-1.764 1.23zm0 3.762h1.898c1.184 0 1.81-.48 1.81-1.377 0-.885-.65-1.348-1.886-1.348H6.375z'/%3E%3Cpath d='M4.002 0a4 4 0 0 0-4 4v8a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4zm1.06 12V3.545h3.399c1.587 0 2.543.809 2.543 2.11 0 .884-.65 1.675-1.483 1.816v.1c1.143.117 1.904.931 1.904 2.033 0 1.488-1.084 2.396-2.888 2.396z'/%3E%3C/svg%3E">
    <link rel="icon" href="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23673ab7' viewBox='0 0 16 16'%3E%3Cpath d='M6.375 7.125V4.658h1.78c.973 0 1.542.457 1.542 1.237 0 .802-.604 1.23-1.764 1.23zm0 3.762h1.898c1.184 0 1.81-.48 1.81-1.377 0-.885-.65-1.348-1.886-1.348H6.375z'/%3E%3Cpath d='M4.002 0a4 4 0 0 0-4 4v8a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4V4a4 4 0 0 0-4-4zm1.06 12V3.545h3.399c1.587 0 2.543.809 2.543 2.11 0 .884-.65 1.675-1.483 1.816v.1c1.143.117 1.904.931 1.904 2.033 0 1.488-1.084 2.396-2.888 2.396z'/%3E%3C/svg%3E">
    <style type="text/css">
        /* Simple Reset */
        blockquote,body,div,fieldset,form,h1,h2,h3,h4,h5,h6,html,input,li,ol,p,span,ul{margin:0;padding:0}
        fieldset,img{border:none;outline:0}
        img{height:auto;max-height:300px;max-width:300px;width:auto}
        li,ol,ul{list-style:none}
        a,a:focus,a:hover{text-decoration:none}
        .fl{float:left}
        .fr{float:right}
        .cl{clear:both}
        /* General Styles */
        body{background:#f7f7f7;font:62.5% Verdana,Arial,Trebuchet MS}
        #loader{position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.3);z-index:99}
        #loader .inner{position:absolute;top:0;right:0;bottom:0;left:0;width:120px;height:60px;margin:auto;padding-top:15px;text-align:center;color:#fff;background-color:rgba(0,0,0,.7);z-index:100;border-radius:15px}
        #headerwrap{width:100%;position:fixed;height:45px;box-shadow:0 0 3px 4px rgba(0,0,0,.3)}
        #header{background:#333;border-top:1px solid #363639;border-bottom:1px solid #151518;background-image:linear-gradient(top,#404048 16%,#2a2a30 58%);height:45px;background-image:-o-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-moz-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-webkit-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-ms-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-webkit-gradient(linear,left top,left bottom,color-stop(.16,#404048),color-stop(.58,#2a2a30))}
        #contentwrap{width:100%;background:#f7f7f7;padding-top:45px}
        #entry-content img {padding:10px 0}
        .post{background:#f7f7f7;border-top:1px solid #fff;padding:8px}
        .post,.single-post{border-bottom:1px solid #e5e5e5}
        .single-post{border-top:1px solid #e5e5e5}
        .single-post a{text-decoration:underline}
        #title{padding:8px 1em;color:#666}
        #title h2{color:#333}
        #info{padding:12px 0 2px;background:#eee;color:#666}
        #info h2{color:#666}
        #info h2,#more{text-align:center}
        #more{background:#f7f7f7}
        #more a{display:block;padding:8px}
        #info a,#more a,#title a{color:#666}
        #loading{background:#f7f7f7 url() 50% no-repeat;clear:both;display:none;font-size:12px;height:30px;padding:5px 0;text-align:center}
        #comments{background:#f7f7f7;text-align:center}
        #comment,input[type=email],input[type=text],input[type=url]{outline:0;width:91%;padding:4px 1%;margin:0 2% 10px;font-size:14px;height:26px;line-height:26px;border:1px solid #777;box-shadow:0 1px 1px #fff,inset 0 2px 6px rgba(0,0,0,.35);border-radius:6px}
        #comment{height:60px}
        input[type=submit]{outline:0;cursor:pointer;width:94%;height:30px;margin:0 2% 10px;color:#fff;font-size:14px;line-height:26px;border:1px solid #777;text-shadow:0 1px 1px rgba(0,0,0,.5);border-radius:6px;background:-webkit-gradient(linear,center top,center bottom,color-stop(.1,#4cabda),color-stop(.8,#1c92c1))}
        #respond a{color:#666;display:block;padding:8px 0}
        #footerwrap{width:100%;text-align:center}
        #footer{background:#f7f7f7;border-top:1px solid #e5e5e5;padding:8px}
        h1{font-size:1.4em;line-height:1.4em;margin:0 0 10px}
        #header h1{float:left;width:74%;height:45px;overflow:hidden;color:#ccc;margin:0;line-height:45px}
        #header h1 a{color:#fff;text-decoration:none;text-shadow:1px 1px 1px #000;padding-left:1em}
        #top-nav{margin-right:1em;padding-top:4px}
        #top-nav,#top-nav li{float:right}
        #header #top-nav li a{color:#c4c4c5;margin:2px 0 0 .5em;display:block;background:#666;border-radius:5px;padding:0 .6em;height:30px;line-height:30px;font-size:14px;font-weight:400;border:1px solid #040405;box-shadow:inset 0 1px 0 0 hsla(0,0%,100%,.1),0 1px 0 0 hsla(0,0%,100%,.1);background-image:linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-o-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-moz-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-webkit-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-ms-linear-gradient(top,#404048 16%,#2a2a30 58%);background-image:-webkit-gradient(linear,left top,left bottom,color-stop(.16,#404048),color-stop(.58,#2a2a30))}
        h2{font-size:1.6em;line-height:1.4em;margin:0 0 10px}
        h2 a,h2.title{color:#333}
        h2.title{margin:0}
        h3,p{font-size:1.2em;line-height:1.4em;margin:0 0 10px}
        p,p a{color:#666}
        #header p{font-size:1.1em;margin:0}
        #header p,#header p a{color:#888}
        .index a{display:block}
        .archive img,.index img{width:90px;height:60px;margin:5px 0 0 5px;border:1px solid #999;box-shadow:0 0 3px rgba(0,0,0,.2);display:block;float:right}
        .post p.subtitle{font-size:1.1em;margin:0}
        .post p.singleline{margin:0}
        .post p.commentfoot{font-size:1.1em}
        .oneline p{margin:0}
        #comments p{font-size:1.1em;margin:0}
        #comments p a{color:#d54e21}
        #footer p{font-size:1.1em;margin:0}
        #footer p,#footer p a{color:#666}
        blockquote{border-left:4px solid #ccc;margin:8px;padding-left:4px}
        .post-comment{border:none}
        /* nav */
        #nav{max-height:200px;min-width:200px;display:none;padding:1em;position:fixed;background:#333;top:55px;border:1px solid #000;box-shadow:0 0 2px 2px rgba(0,0,0,.5);border-radius:4px;right:1em}
        #nav dl{margin:0}
        #nav dd,#nav dt{padding:0;color:#999;font-size:12px}
        #nav a{color:#f7f7f7;padding:.5em 0;display:block;float:left;margin:0 1em}
        /* Bootstrap-highlighting-of-code */
        .prettyprint li,.prettyprint ol,.prettyprint ul{list-style:decimal}
        .prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}
        .prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;-moz-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}
        .com{color:#93a1a1}
        .lit{color:#195f91}
        .clo,.opn,.pun{color:#93a1a1}
        .fun{color:#dc322f}
        .atv,.str{color:#d14}
        .kwd,.linenums .tag{color:#1e347b}
        .atn,.dec,.typ,.var{color:teal}
        .pln{color:#48484c}
        ol.linenums{margin:0 0 0 33px}
        ol.linenums li{padding-left:12px;color:#bebec5;line-height:18px;text-shadow:0 1px 0 #fff}
        code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,Courier New,monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
        code{padding:3px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;border-image:initial}
        pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all}
        pre.prettyprint{margin-bottom:18px}
        pre code{padding:0;background-color:transparent}
        /* Glyphicons */
        .icon{display:inline-block;width:14px;height:14px;line-height:14px;background-image:url();background-position:14px 14px;background-repeat:no-repeat;vertical-align:text-top}
        .icon-white{background-image:url()}
        .muted{opacity:.5}
        .icon-spin{background-position:-240px -24px;-o-animation:icon-spin-circle 2s infinite linear;-webkit-animation:icon-spin-circle 2s linear infinite;-moz-animation:icon-spin-circle 2s infinite linear;-ms-animation:icon-spin-circle 2s infinite linear;animation:icon-spin-circle 2s linear infinite}
        @-o-keyframes icon-spin-circle{0%{-o-transform:rotate(0)}
        to{-o-transform:rotate(1turn)}
        }
        @-webkit-keyframes icon-spin-circle{0%{-webkit-transform:rotate(0)}
        to{-webkit-transform:rotate(1turn)}
        }
        @-moz-keyframes icon-spin-circle{0%{-moz-transform:rotate(0)}
        to{-moz-transform:rotate(1turn)}
        }
        @-ms-keyframes icon-spin-circle{0%{-ms-transform:rotate(0)}
        to{-ms-transform:rotate(1trun)}
        }
        @keyframes icon-spin-circle{0%{transform:rotate(0)}
        to{transform:rotate(1turn)}
        }
        /* First line */
        .icon-glass{background-position:0 0}
        .icon-music{background-position:-24px 0}
        .icon-search{background-position:-48px 0}
        .icon-envelope{background-position:-72px 0}
        .icon-heart{background-position:-96px 0}
        .icon-star{background-position:-120px 0}
        .icon-star-empty{background-position:-144px 0}
        .icon-user{background-position:-168px 0}
        .icon-film{background-position:-192px 0}
        .icon-th-large{background-position:-216px 0}
        .icon-th{background-position:-240px 0}
        .icon-th-list{background-position:-264px 0}
        .icon-ok{background-position:-288px 0}
        .icon-remove{background-position:-312px 0}
        .icon-zoom-in{background-position:-336px 0}
        .icon-zoom-out{background-position:-360px 0}
        .icon-off{background-position:-384px 0}
        .icon-signal{background-position:-408px 0}
        .icon-cog{background-position:-432px 0}
        .icon-trash{background-position:-456px 0}
        /* Second line */
        .icon-home{background-position:0 -24px}
        .icon-file{background-position:-24px -24px}
        .icon-time{background-position:-48px -24px}
        .icon-road{background-position:-72px -24px}
        .icon-download-alt{background-position:-96px -24px}
        .icon-download{background-position:-120px -24px}
        .icon-upload{background-position:-144px -24px}
        .icon-inbox{background-position:-168px -24px}
        .icon-play-circle{background-position:-192px -24px}
        .icon-repeat{background-position:-216px -24px}
        .icon-refresh{background-position:-240px -24px}
        .icon-list-alt{background-position:-264px -24px}
        .icon-lock{background-position:-287px -24px}
        .icon-flag{background-position:-312px -24px}
        .icon-headphones{background-position:-336px -24px}
        .icon-volume-off{background-position:-360px -24px}
        .icon-volume-down{background-position:-384px -24px}
        .icon-volume-up{background-position:-408px -24px}
        .icon-qrcode{background-position:-432px -24px}
        .icon-barcode{background-position:-456px -24px}
        /* Third line */
        .icon-tag{background-position:0 -48px}
        .icon-tags{background-position:-25px -48px}
        .icon-book{background-position:-48px -48px}
        .icon-bookmark{background-position:-72px -48px}
        .icon-print{background-position:-96px -48px}
        .icon-camera{background-position:-120px -48px}
        .icon-font{background-position:-144px -48px}
        .icon-bold{background-position:-167px -48px}
        .icon-italic{background-position:-192px -48px}
        .icon-text-height{background-position:-216px -48px}
        .icon-text-width{background-position:-240px -48px}
        .icon-align-left{background-position:-264px -48px}
        .icon-align-center{background-position:-288px -48px}
        .icon-align-right{background-position:-312px -48px}
        .icon-align-justify{background-position:-336px -48px}
        .icon-list{background-position:-360px -48px}
        .icon-indent-left{background-position:-384px -48px}
        .icon-indent-right{background-position:-408px -48px}
        .icon-facetime-video{background-position:-432px -48px}
        .icon-picture{background-position:-456px -48px}
        /* Fourth line */
        .icon-pencil{background-position:0 -72px}
        .icon-map-marker{background-position:-24px -72px}
        .icon-adjust{background-position:-48px -72px}
        .icon-tint{background-position:-72px -72px}
        .icon-edit{background-position:-96px -72px}
        .icon-share{background-position:-120px -72px}
        .icon-check{background-position:-144px -72px}
        .icon-move{background-position:-168px -72px}
        .icon-step-backward{background-position:-192px -72px}
        .icon-fast-backward{background-position:-216px -72px}
        .icon-backward{background-position:-240px -72px}
        .icon-play{background-position:-264px -72px}
        .icon-pause{background-position:-288px -72px}
        .icon-stop{background-position:-312px -72px}
        .icon-forward{background-position:-336px -72px}
        .icon-fast-forward{background-position:-360px -72px}
        .icon-step-forward{background-position:-384px -72px}
        .icon-eject{background-position:-408px -72px}
        .icon-chevron-left{background-position:-432px -72px}
        .icon-chevron-right{background-position:-456px -72px}
        /* Fifth line */
        .icon-plus-sign{background-position:0 -96px}
        .icon-minus-sign{background-position:-24px -96px}
        .icon-remove-sign{background-position:-48px -96px}
        .icon-ok-sign{background-position:-72px -96px}
        .icon-question-sign{background-position:-96px -96px}
        .icon-info-sign{background-position:-120px -96px}
        .icon-screenshot{background-position:-144px -96px}
        .icon-remove-circle{background-position:-168px -96px}
        .icon-ok-circle{background-position:-192px -96px}
        .icon-ban-circle{background-position:-216px -96px}
        .icon-arrow-left{background-position:-240px -96px}
        .icon-arrow-right{background-position:-264px -96px}
        .icon-arrow-up{background-position:-289px -96px}
        .icon-arrow-down{background-position:-312px -96px}
        .icon-share-alt{background-position:-336px -96px}
        .icon-resize-full{background-position:-360px -96px}
        .icon-resize-small{background-position:-384px -96px}
        .icon-plus{background-position:-408px -96px}
        .icon-minus{background-position:-433px -96px}
        .icon-asterisk{background-position:-456px -96px}
        /* Sixth line */
        .icon-exclamation-sign{background-position:0 -120px}
        .icon-gift{background-position:-24px -120px}
        .icon-leaf{background-position:-48px -120px}
        .icon-fire{background-position:-72px -120px}
        .icon-eye-open{background-position:-96px -120px}
        .icon-eye-close{background-position:-120px -120px}
        .icon-warning-sign{background-position:-144px -120px}
        .icon-plane{background-position:-168px -120px}
        .icon-calendar{background-position:-192px -120px}
        .icon-random{background-position:-216px -120px;width:16px}
        .icon-comment{background-position:-240px -120px}
        .icon-magnet{background-position:-264px -120px}
        .icon-chevron-up{background-position:-288px -120px}
        .icon-chevron-down{background-position:-313px -119px}
        .icon-retweet{background-position:-336px -120px}
        .icon-shopping-cart{background-position:-360px -120px}
        .icon-folder-close{background-position:-384px -120px;width:16px}
        .icon-folder-open{background-position:-408px -120px;width:16px}
        .icon-resize-vertical{background-position:-432px -119px}
        .icon-resize-horizontal{background-position:-456px -118px}
        /* Seventh line */
        .icon-hdd{background-position:0 -144px}
        .icon-bullhorn{background-position:-24px -144px}
        .icon-bell{background-position:-48px -144px}
        .icon-certificate{background-position:-72px -144px}
        .icon-thumbs-up{background-position:-96px -144px}
        .icon-thumbs-down{background-position:-120px -144px}
        .icon-hand-right{background-position:-144px -144px}
        .icon-hand-left{background-position:-168px -144px}
        .icon-hand-up{background-position:-192px -144px}
        .icon-hand-down{background-position:-216px -144px}
        .icon-circle-arrow-right{background-position:-240px -144px}
        .icon-circle-arrow-left{background-position:-264px -144px}
        .icon-circle-arrow-up{background-position:-288px -144px}
        .icon-circle-arrow-down{background-position:-312px -144px}
        .icon-globe{background-position:-336px -144px}
        .icon-wrench{background-position:-360px -144px}
        .icon-tasks{background-position:-384px -144px}
        .icon-filter{background-position:-408px -144px}
        .icon-briefcase{background-position:-432px -144px}
        .icon-fullscreen{background-position:-456px -144px}
    </style>
</head>

<body>
    <div id="app"></div>
    <script type="text/javascript">
        var render = {
            toggleNav: false,
            textFontSize: 1.2,
            api: document.domain.match(/localhost|127.0.0.1/) ? '/' : (document.location.protocol == 'https:' ? 'https://yesu.co/' : 'http://yesu.co/'),
            path: '/',
            url: '',
            lang: 'zh-CN',
            langs: ['co', 'gn', 'rw', 'ha', 'no', 'af', 'yo', 'en', 'gom', 'la', 'ne', 'fr', 'cs', 'haw', 'ka', 'ru', 'zh-CN', 'fa', 'bho', 'hi', 'be', 'sw', 'is', 'yi', 'ak', 'ga', 'gu', 'km', 'sk', 'iw', 'kn', 'hu', 'ta', 'ar', 'bn', 'az', 'sm', 'su', 'da', 'sn', 'bm', 'lt', 'vi', 'mt', 'tk', 'as', 'ca', 'si', 'ceb', 'gd', 'sa', 'pl', 'gl', 'lv', 'uk', 'tt', 'cy', 'ja', 'tl', 'ay', 'lo', 'te', 'ro', 'ht', 'doi', 'sv', 'mai', 'th', 'hy', 'my', 'ps', 'hmn', 'dv', 'zh-TW', 'lb', 'sd', 'ku', 'tr', 'mk', 'bg', 'ms', 'lg', 'mr', 'et', 'ml', 'de', 'sl', 'ur', 'pt', 'ig', 'ckb', 'om', 'el', 'es', 'fy', 'so', 'am', 'ny', 'pa', 'eu', 'it', 'sq', 'ko', 'tg', 'fi', 'ky', 'ee', 'hr', 'qu', 'bs', 'mi', 'or', 'ti', 'kk', 'nl', 'kri', 'ln', 'mg', 'mn', 'lus', 'xh', 'zu', 'sr', 'nso', 'st', 'eo', 'mni-Mtei', 'ug', 'uz', 'ilo', 'id', 'jw', 'ts'],
            timer: null,
            init: function() {
                window.addEventListener('hashchange', render.router, false);
                window.addEventListener('load', render.router, false);
                window.addEventListener('click', render.click, false);
                window.addEventListener('change', render.change, false);
                window.addEventListener('keyup', render.keyup, false);
                window.addEventListener('scroll', render.scroll, false);
            },

            // hash router
            router: function() {
                var hash = location.hash.replace('#', '');
                render.path = hash === '' ? '/' : hash;
                render.url = render.api + 'api' + render.path;
                var parts = render.path.split('/');
                if (render.langs.indexOf(parts[1]) !== -1) {
                    render.lang = parts[1];
                    parts[0] = parts[1];
                    parts[1] = 'api';
                    render.url = render.api + parts.join('/');
                }
                if (render.path.match(/\/page-(\d+).html$/)) {
                    document.getElementById('more') && document.getElementById('more').parentNode.removeChild(document.getElementById('more'));
                    document.getElementById('loading') && (document.getElementById('loading').style.cssText = 'display: block;');
                } else {
                    document.getElementById('app').insertAdjacentHTML('afterbegin', render.loader());
                }
                render.toggleNav = false;
                document.getElementById('nav') && (document.getElementById('nav').style.cssText = 'display: none;');
                render.ajax('get', render.url, null, render.success, render.fail);
            },

            // click event
            click: function(e) {
                // Show nav menu
                if ((e.target.tagName === 'I' && e.target.className.match(/icon-tasks/)) || (e.target.tagName === 'A' && e.target.id === 'shownav')) {
                    render.toggleNav = !render.toggleNav;
                    if (render.toggleNav) {
                        document.getElementById('nav') && (document.getElementById('nav').style.cssText = 'display: block;');
                    } else {
                        document.getElementById('nav') && (document.getElementById('nav').style.cssText = 'display: none;');
                    }
                } else {
                    var flag = false;
                    var node = e.target;
                    while(node) {
                        if (node.id === 'nav') {
                            flag = true;
                            break;
                        }
                        node = node.parentNode;
                    }
                    if (!node) {
                        render.toggleNav = false;
                        document.getElementById('nav') && (document.getElementById('nav').style.cssText = 'display: none;');
                    }
                }
                // Font zoom
                if (e.target.tagName === 'I' && (e.target.id === 'smaller' || e.target.id === 'bigger')) {
                    render[e.target.id]();
                }
                // To top
                e.target.tagName === 'A' && e.target.id === 'top' && render.top();
            },

            // change event
            change: function(e) {
                // Language select
                if (e.target.tagName === 'SELECT' && e.target.id === 'lang') {
                    var lang = render.lang;
                    render.lang = e.target.value;
                    document.getElementsByTagName('html')[0].setAttribute('lang', render.lang);
                    location.hash = '#'+ (render.lang.match(/^zh-/) ? '' : '/' + render.lang) + render.path.replace(new RegExp('^/'+ lang +'/'), '/');
                }
            },

            // keyup event
            keyup: function(e) {
                if (e.target.tagName === 'INPUT' && e.target.id === 'search-text' && e.keyCode === 13) {
                    var q = document.getElementById('search-text').value.trim();
                    if (!q.length) return false;
                    location.hash = '#/'+ (render.lang.match(/^zh-/) ? '' : render.lang +'/') +'search.html?q='+ q;
                }
            },

            // scroll event
            scroll: function(e) {
                if (render.timer) return false;
                render.timer = setTimeout(function() {
                    render.lazyLoad();
                    render.timer = null;
                }, 300);
            },

            // lazyload images
            lazyLoad: function() {
                var clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
                var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
                if (document.getElementById('loop')) {
                    var imgs = document.getElementById('loop').getElementsByTagName('img');
                    for (var i = 0; i < imgs.length; i++) {
                        var pos = 0;
                        var img = imgs[i];
                        var elem = imgs[i];
                        while (elem) {
                            pos += elem.offsetTop;
                            elem = elem.offsetParent;
                        }
                        if (pos < clientHeight + scrollTop && img.src.match(/^data:image/)) {
                            img.src = img.getAttribute('data-src');
                        }
                    }
                }
            },

            // Route to page
            success: function(res) {
                if (res.code) return render.err404(res);
                document.title = res.data.header.title.join('-');
                var arr = [];
                arr.push(render.header(res.data));
                arr.push(render.main(res.data));
                arr.push(render.footer(res.data));
                arr.push(render.nav(res.data));
                document.getElementById('app').innerHTML = arr.join('\n');
                !render.path.match(/\/page-(\d+).html$/) && render.top();
                render.lazyLoad();
            },

            // err404
            err404: function(res) {
                if (res.code) {
                    document.getElementById('app').innerHTML = render.info('Error', res.msg);
                } else {
                    return render.info();
                }
            },

            // header
            header: function(data) {
                var arr = [];
                arr.push('<div id="headerwrap">\n');
                arr.push('\t<div id="header">\n');
                arr.push('\t\t<h1><a href="#/'+ (render.lang.match(/^zh-/) ? '' : render.lang + '/') +'">'+ data.setting.webName +'</a></h1>\n');
                arr.push('\t\t<ul id="top-nav">\n');
                arr.push('\t\t\t<li><a id="shownav" href="javascript:;" title="Nav menu"><i class="icon icon-white icon-tasks"></i></a></li>\n');
                arr.push('\t\t\t<li><a href="#/'+ (render.lang.match(/^zh-/) ? '' : render.lang + '/') +'" title="Home"><i class="icon icon-white icon-home"></i></a></li>\n');
                arr.push('\t\t</ul>\n');
                arr.push('\t\t<div class="cl"></div>\n');
                arr.push('\t</div>\n');
                arr.push('</div>\n');
                return arr.join('');
            },

            // main
            main: function(data) {
                var arr = [];
                arr.push('<div id="contentwrap" class="'+ (data.is_index ? 'index' : (data.is_detail || data.is_page || (data.is_category && data.category.is_gallery == '1') ? '' : 'archive')) +'">\n');
                !data.is_index && arr.push('\t<div id="title">'+ render.crumbs(data) +'</div>\n');
                if (data.is_404) {
                    arr.push(render.err404(data));
                } else {
                    if (data.is_detail || data.is_page) {
                        arr.push(render[data.action](data));
                    } else {
                        arr.push(render.archive(data));
                    }
                }
                arr.push('</div>\n');
                return arr.join('');
            },

            // footer
            footer: function(data) {
                var arr = [];
                var t = new Date().getFullYear();
                arr.push('<div id="footerwrap" class="position">\n');
                arr.push('\t<div id="footer">\n');
                if (data.is_index && data.footer.link.length) {
                    arr.push('\t\t<p>\n');
                    arr.push('\t\t\t<a href="'+ data.site_url +'/" title="'+ data.setting.webName +'">'+ data.setting.webName +'</a>');
                    data.footer.link.forEach(function(item, i) {
                        arr.push('&nbsp;-&nbsp;<a href="'+ item.url +'" title="'+ item.name +'">'+ item.name +'</a>');
                    });
                    arr.push('\t\t</p>\n');
                }
                arr.push('\t\t<p><a href="javascript:;" title="Top" id="top">↑Top</a> | <a href="'+ data.site_url + render.path +'" title="Desktop view">Desktop view</a></p>\n');
                arr.push('\t\t<p>&copy; 2024'+ (t > 2024 ? ' - '+ t : '') +'</p>\n');
                arr.push('\t</div>\n');
                arr.push('</div>\n');
                return arr.join('');
            },

            // nav menu
            nav: function(data) {
                var arr = [];
                arr.push('<div id="nav">\n');
                arr.push('\t<dl>\n');
                arr.push('\t\t<dt><input id="search-text" type="text" placeholder="Search ..." /></dt>\n');
                arr.push('\t</dl>\n');
                arr.push('\t<div class="cl"></div>\n');
                // Categories
                if (data.header.nav.length) {
                    arr.push('\t<dl>\n');
                    data.header.nav.forEach(function(el, i) {
                        if (el.children.length) {
                            arr.push('\t\t<dt>'+ el.name +'</dt>\n');
                            el.children.forEach(function(ele, j) {
                                arr.push('\t\t<dd><a href="#'+ ele.link +'" title="'+ ele.name +'">'+ ele.name +'</a></dd>\n');
                            });
                        } else {
                            arr.push('\t\t<dt><a href="#'+ el.link +'" title="'+ el.name +'">'+ el.name +'</a></dt>\n');
                        }
                    });
                    arr.push('\t</dl>\n');
                    arr.push('\t<div class="cl"></div>\n');
                }
                // Languages
                if (data.langs && data.langs.length) {
                    arr.push('\t<dl>\n');
                    arr.push('\t\t<dt>Languages:</dt>\n');
                    arr.push('\t</dl>\n');
                    arr.push('\t<div class="cl"></div>\n');
                    arr.push('\t<select id="lang" style="margin-top:10px;padding:2px;">\n');
                    data.langs.forEach(function(item, i) {
                        arr.push('\t\t<option value="'+ item.slug +'"'+ (item.slug === render.lang ? ' selected="selected"' : '') +'>'+ item.title +' ('+ item.name +')</option>\n');
                    });
                    arr.push('\t</select>\n');
                    arr.push('\t<div class="cl"></div>\n');
                }
                return arr.join('');
            },

            // crumbs
            crumbs: function(data) {
                var arr = [];
                data.header.crumbs.forEach(function(item, i) {
                    if (item.link !== undefined) {
                        arr.push('<a href="#'+ item.link +'" title="'+ item.name +'">'+ item.name +'</a>');
                    } else {
                        arr.push(item.name);
                    }
                });
                return arr.join(' > ');
            },

            // detail
            detail: function(data) {
                var arr = [];
                var t = new Date(data.article.create_at * 1000);
                var y = t.getFullYear() + '';
                var m = ('0' + (t.getMonth() + 1)).slice(-2);
                var d = ('0' + t.getDate()).slice(-2);
                arr.push('<div class="post single-post">\n');
                arr.push('\t<h2>'+ data.article.title +'</h2>\n');
                arr.push('\t<div class="subtitle">\n');
                arr.push('\t\t<p class="fl">\n');
                arr.push('\t\t\t<i class="icon icon-time muted"></i> '+ (m +'/'+ d +'/'+ y.slice(2)) +' &nbsp;\n');
                arr.push('\t\t\t<i class="icon icon-eye-open muted"></i> '+ data.main.article.views +' &nbsp;\n');
                arr.push('\t\t\t<i class="icon icon-folder-open muted"></i> <a href="#'+ data.category.link +'" title="'+ data.category.name +'">'+ data.category.name +'</a>\n');
                arr.push('\t\t</p>\n');
                arr.push('\t\t<div class="fr muted">\n');
                arr.push('\t\t\t<i class="icon icon-font" id="bigger"></i><sup>+</sup> &nbsp;\n');
                arr.push('\t\t\t<i class="icon icon-font" id="smaller"></i><sup>-</sup> &nbsp;\n');
                arr.push('\t\t</div>\n');
                arr.push('\t</div>\n');
                arr.push('\t<div class="cl"></div>\n');
                arr.push('\t<div id="entry-content">'+ data.article.content +'</div>\n');
                if (data.main.tags.length) {
                    arr.push('\t<p class="subtitle">\n');
                    arr.push('\t\t<i class="icon icon-tags"></i> &nbsp;');
                    data.main.tags.forEach(function(item, i) {
                        arr.push((i > 0 ? ', ' : '') + '<a href="#'+ item.link +'" title="'+ item.name +'">'+ item.name +'</a>');
                    });
                    arr.push('\t</p>\n');
                }
                arr.push('</div>\n');
                if (data.main.comments.length) {
                    arr.push('<div class="comments" id="loop">\n');
                    document.getElementById('loop') && render.path.match(/\/page-(\d+).html/) && arr.push(document.getElementById('loop').innerHTML);
                    data.main.comments.forEach(function(item, i) {
                        var t = new Date(item.time * 1000);
                        var y = t.getFullYear() + '';
                        var m = ('0' + (t.getMonth() + 1)).slice(-2);
                        var d = ('0' + t.getDate()).slice(-2);
                        arr.push('\t<div class="post">\n');
                        arr.push('\t\t<p><cite>'+ (item.nickname ? item.nickname : 'anonymous') +'</cite> says:</p>\n');
                        arr.push('\t\t'+ item.comment +'\n');
                        arr.push('\t\t<p class="singleline commentfoot">Posted on time '+ (m +'/'+ d +'/'+ y.slice(2)) +'</p>\n');
                        arr.push('\t</div>\n');
                    });
                    arr.push('</div>\n');
                    arr.push('<div id="loading"></div>\n');
                    arr.push(render.pager(data.main.pager, data.p));
                } else {
                    arr.push('<div id="comments">\n');
                    arr.push('\t<div id="respond">\n');
                    arr.push('\t\t<a href="javascript:;" title="Reached end">Reached end</a>\n');
                    arr.push('\t</div>\n');
                    arr.push('</div>\n');
                }
                return arr.join('');
            },

            // page
            page: function(data) {
                var arr = [];
                arr.push('<div class="post">\n');
                arr.push('\t'+ data.page.content +'\n');
                arr.push('</div>\n');
                return arr.join('');
            },

            // archive
            archive: function(data) {
                var arr = [];
                if (data.main.list.length) {
                    arr.push('<div id="loop">\n');
                    document.getElementById('loop') && render.path.match(/\/page-(\d+).html/) && arr.push(document.getElementById('loop').innerHTML);
                    data.main.list.forEach(function(item, i) {
                        arr.push('\t<div class="post">\n');
                        arr.push('\t\t<a href="#'+ item.link +'" title="'+ item.title +'">\n');
                        arr.push('\t\t\t<h2 class="title">'+ item.title +'</h2>\n');
                        item.cover && arr.push('\t\t\t<img src="" data-src="'+ item.cover +'" alt="'+ item.title +'" title="'+ item.title +'" class="thumbnail"'+ (data.is_category && data.category.is_gallery == '1' ? ' style="max-width:100%;"' : '') +' />\n');
                        if (!data.is_category || data.category.is_gallery != '1') {
                            var t = new Date(item.create_at * 1000);
                            var y = t.getFullYear() + '';
                            var m = ('0' + (t.getMonth() + 1)).slice(-2);
                            var d = ('0' + t.getDate()).slice(-2);
                            arr.push('\t\t\t<div class="decoration">\n');
                            arr.push('\t\t\t\t<p class="subtitle"><i class="icon icon-time muted"></i> '+ (m +'/'+ d +'/'+ y.slice(2)) +' &nbsp; <i class="icon icon-eye-open muted"></i> '+ item.views +'</p>\n');
                            arr.push('\t\t\t\t<p>'+ (item.description ? item.description : render.cutstr(item.content.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' '), 140)) +'</p>\n');
                            arr.push('\t\t\t\t<div class="cl"></div>\n');
                            arr.push('\t\t\t</div>\n');
                        }
                        arr.push('\t\t</a>\n');
                        if (data.is_category && data.category.is_gallery == '1') arr.push('\t<div class="cl"></div>\n');
                        arr.push('\t</div>\n');
                    });
                    arr.push('</div>\n');
                    arr.push('<div id="loading"></div>\n');
                    arr.push(render.pager(data.main.pager, data.p));
                } else {
                    arr.push(render.info('No posts', 'There have no posts' + (data.is_search ? ' search for "'+ data.q +'"' : '')));
                }
                return arr.join('');
            },

            // pager
            pager: function(datas, per) {
                var obj = datas[datas.length - 1];
                var arr = [];
                arr.push('<div id="more" class="position">\n');
                if (obj.p === per) {
                    arr.push('\t<a href="javascript:;" title="Reached end">Reached end</a>\n');
                } else {
                    arr.push('\t<a href="#'+ obj.link +'" title="'+ obj.title +'">'+ obj.title +'</a>\n');
                }
                arr.push('</div>\n');
                return arr.join('');
            },

            // fail
            fail: function(status, statusText) {
                var codeMsg = {
                    301: {
                        title: '301 Moved Permanently',
                        msg: 'The requested page has moved to a new URL'
                    },
                    302: {
                        title: '302 Found',
                        msg: 'The requested page has moved temporarily to a new URL'
                    },
                    400: {
                        title: '400 Bad Request',
                        msg: 'The request cannot be fulfilled due to bad syntax'
                    },
                    401: {
                        title: '401 Unauthorized',
                        msg: 'The request was a legal request, but the server is refusing to respond to it. For use when authentication is possible but has failed or not yet been provided'
                    },
                    403: {
                        title: '403 Forbidden',
                        msg: 'The request was a legal request, but the server is refusing to respond to it'
                    },
                    404: {
                        title: '404 Not Found',
                        msg: 'The requested page could not be found but may be available again in the future'
                    },
                    408: {
                        title: '408 Request Timeout',
                        msg: 'The server timed out waiting for the request'
                    },
                    500: {
                        title: '500 Internal Server Error',
                        msg: 'A generic error message, given when no more specific message is suitable'
                    },
                    501: {
                        title: '501 Not Implemented',
                        msg: 'The server either does not recognize the request method, or it lacks the ability to fulfill the request'
                    },
                    502: {
                        title: '502 Bad Gateway',
                        msg: 'The server was acting as a gateway or proxy and received an invalid response from the upstream server'
                    },
                    503: {
                        title: '503 Service Unavailable',
                        msg: 'The server is currently unavailable (overloaded or down)'
                    },
                    504: {
                        title: '504 Gateway Timeout',
                        msg: 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server'
                    },
                    505: {
                        title: '505 HTTP Version Not Supported',
                        msg: 'The server does not support the HTTP protocol version used in the request'
                    },
                };
                document.getElementById('app').innerHTML = render.info(codeMsg[status] ? codeMsg[status].title : 'Error', codeMsg[status] ? codeMsg[status].msg : (statusText ? statusText : 'Status code: '+ status));
            },

            // info
            info: function (title, msg) {
                var arr = [];
                arr.push('<div id="info">\n');
                arr.push('\t<h2>'+ (title ? title : 'Page Not Found') +'</h2>\n');
                arr.push('</div>');
                arr.push('<div class="post">\n');
                arr.push('\t<p>'+ (msg ? msg : 'Sorry, The page you are looking for cannot be found!') +'</p>\n');
                arr.push('</div>\n');
                return arr.join('');
            },

            // cutstr
            cutstr: function (str, n, suffix) {
                var len = 0;
                var arr = [];
                for (var i in str) {
                    arr.push(str[i]);
                    len += str[i].length;
                    if (str[i].charCodeAt(0).toString(16).length == 4) {
                        len += 1;
                    }
                    if (len > n) {
                        arr.pop();
                        arr.push(suffix || '...');
                        break;
                    }
                }
                return arr.join('');
            },

            // Font zoom
            bigger: function () {
                if (render.textFontSize <= 2.4) {
                    render.textFontSize += 0.2;
                }
                document.getElementById("entry-content").style.cssText = "font-size:" + render.textFontSize + "em";
            },
            smaller: function () {
                if (render.textFontSize >= 1.2) {
                    render.textFontSize -= 0.2;
                }
                document.getElementById("entry-content").style.cssText = "font-size:" + render.textFontSize + "em";
            },

            // To top
            top: function() {
                var distance = document.documentElement.scrollTop || document.body.scrollTop;
                var timer = setInterval(function () {
                    distance += Math.floor((0 - distance) / 10);
                    window.scrollTo(0, Math.max(distance, 0));
                    if (distance <= 0) {
                        window.scrollTo(0, 0);
                        clearInterval(timer);
                        timer = null;
                    }
                }, 10);
            },

            // loader
            loader: function() {
                var arr = [];
                arr.push('<div id="loader">\n');
                arr.push('\t<div class="inner">\n');
                arr.push('\t\t<h1>Loading...</h1>\n');
                arr.push('\t\t<i class="icon icon-spin icon-white"></i>\n');
                arr.push('\t</div>\n');
                arr.push('</div>\n');
                return arr.join('');
            },

            // Ajax request
            ajax: function(type, url, data, callback, fail) {
                type = (type || 'GET').toUpperCase();
                var xhr = new XMLHttpRequest();
                var params = '';
                var datas = typeof data === 'function' ? data() : data;
                if (!(typeof FormData !== 'undefined' && datas instanceof FormData) && datas && typeof datas === 'object') {
                    for (var key in datas) {
                        if (params) params += '&';
                        params += encodeURIComponent(key) +'='+  encodeURIComponent(datas[key]);
                    }
                } else {
                    params = datas;
                }
                if (type === 'GET') {
                    xhr.open(type, url + (params ? ((url.indexOf('?') === -1 ? '?' : '&') + params +'&__v='+ new Date().getTime() + parseInt(Math.random() * 1000)) : ''), true);
                    params = null;
                } else if (type === 'POST') {
                    xhr.open(type, url, true);
                    if (typeof FormData === 'undefined' || !(params instanceof FormData)) {
                        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
                    }
                }
                xhr.timeout = 30000;
                xhr.send(params);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                            var x = xhr.responseText;
                            if (typeof callback === 'function') {
                                try {
                                    callback(JSON.parse(xhr.responseText));
                                } catch(e) {
                                    callback({code: 1, msg: 'JSON data parse error!'});
                                }
                            }
                        } else {
                            typeof fail === 'function' && fail(xhr.status);
                        }
                    }
                }
                xhr.ontimeout = function() {
                    typeof fail === 'function' && fail(408);
                }
                xhr.onerror = function() {
                    typeof fail === 'function' && fail(xhr.status, xhr.statusText);
                }
            },

            // jsonp request
            jsonp: function(url, callback, jsonpCallback) {
                var script = document.createElement('script');
                var globFuncName = 'undefined' !== typeof jsonpCallback ? jsonpCallback : 'jsonp_' + new Date().getTime() + parseInt(Math.random() * 1000);
                script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'callback='+ globFuncName;
                document.head.appendChild(script).parentNode.removeChild(script);
                window[globFuncName] = function (data) {
                    callback && callback(data);
                    window[globFuncName] = null;
                }
            }
        }
        render.init();
    </script>
</body>
</html>